#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "Objsocket.h"

/*1: path, 2 ip, 3 puerto, 4 tamaño bloque en KB*/

int main(int argc, char *argv[]){
register char fd;
register int escrito=0,leido=1,recivido=0,aux=1,caracteres=1024*atoi(argv[4]);
register unsigned long total=0,tamanio=0;
char buff[caracteres+1],longitud[20]/*,nombre[32]*/;

Socket_T *sock;
Socket_T *AcceptConect;

		sock=NewSocketStream();
		sock->Open(sock);
		sock->Set_dir(sock,argv[2]);
		printf("Dir :%s\n",argv[1]);
		printf("La dir es :[%s] \n",sock->Get_dir(*sock));
		sock->Set_family(sock,AF_INET);
		sock->Set_port(sock,atoi(argv[3]));
		printf("El puerto es :[%d] \n",sock->Get_port(*sock));
		sock->reutilizar_puerto(sock);
		sock->bindear(sock);
		sock->Set_MaxCon(sock,2);
		printf("Maximo de conecciones: [%d] \n",(sock->Get_MaxCon(sock)));
		printf("Tamaño de paquetes: %d\n",caracteres);
		sock->EscuchaPorConecciones(sock);
		AcceptConect=NewSocketStream();
    sock->AceptaConecciones(sock,AcceptConect);

//recivo el tamanio del archivo
		memset(longitud,0,20);
		if(recv(AcceptConect->Get_fd(*AcceptConect),longitud,16,0)==-1){
			perror("recv");
			return -1;
		}

		tamanio=atoi(longitud);

		if((fd=open(argv[1],O_CREAT | O_WRONLY | O_TRUNC | O_APPEND, S_IRWXU))==-1){
				perror("open");
				printf("Dir :%s\n",argv[1]);
				return -1;
		}else printf("Se creo el archivo:%s \n",argv[1]);

while(leido){

    if(send(AcceptConect->Get_fd(*AcceptConect),"s",1,0)==-1){
			perror("send");
			return -1;
		}

    memset(longitud,0,20);
		if(recv(AcceptConect->Get_fd(*AcceptConect),longitud,16,0)==-1){
			perror("recv");
			return -1;
		}

		leido=atoi(longitud);
    if(send(AcceptConect->Get_fd(*AcceptConect),"s",1,0)==-1){
			perror("send");
			return -1;
		}

		memset(buff,0,caracteres+1);
    for(;recivido<leido;){
		  	if((recivido=recivido+recv(AcceptConect->Get_fd(*AcceptConect),buff+recivido,leido-recivido,0))==-1){
					perror("recv");
					return -1;
					}
    }

		total=total+recivido;
		
		printf("Recivido :%d%\r",(total*100)/tamanio);
		recivido=0;

		for(;aux;){
				aux=0;
				if((aux=+write(fd,buff+escrito,leido-escrito))==-1){
					perror("write");
					return -1;
				}
				escrito=+aux;
				}

		escrito=0;aux=1;

}
		close(fd);	
		//calculo de md5
		unsigned char size=strlen(argv[1])+strlen("md5sum ")+strlen(" > md5R")+1;
		char* cmdVerifMd5Sum=(char*) calloc(sizeof(char) * size,size);
		strcat(cmdVerifMd5Sum,"md5sum ");
		strcat(cmdVerifMd5Sum,argv[1]);
		strcat(cmdVerifMd5Sum," > md5R");
		
		if(system(cmdVerifMd5Sum)==-1)
				perror("system");

		//levanto el resultado
		unsigned char lengt = strlen("5b9ed4f95c4bec42cf81e6abba225a0d");
		char cmdrta[lengt+1];
		memset(cmdrta,0,lengt+1);
		unsigned char md5fd=open("md5R",O_RDONLY);
		read(md5fd,cmdrta,lengt);		
		printf("\nmd5sum local: [%s] \n",cmdrta);
		close(md5fd);

		//recivo el md5 del server
		char md5server[lengt+1]; //pedir el tamanio luego
		memset(md5server,0,lengt+1);
		if(recv(AcceptConect->Get_fd(*AcceptConect),md5server,lengt,0)==-1){
			perror("recv");
			return -1;
		}

		printf("md5 recivido: [%s] \n",md5server);
		if(!strcmp(md5server,cmdrta))
			printf("Se recivio correctamente el archivo \n");
		else
			printf("Llego para el culo \n");
		
		sock->closeSocket(*sock);
		sock->closeSocket(*AcceptConect);
		free(sock->Attr);
		free(sock);
		free(AcceptConect->Attr);
		free(AcceptConect);
		printf("total recivido %lu\n",total);
		return 0;
}

